<?php

namespace app\api\model;

use app\api\model\PlatformLog;
use app\common\library\IdentityCard;
use app\common\library\Token;
use app\common\model\BaseModel;
use app\common\model\Config;
use EasyWeChat\Factory;
use think\facade\Db;

class Order extends BaseModel
{
    // 表名
    protected $name = 'order';
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    // 追加属性
    protected $append = [
    ];

    /**
     * 订单列表.
     */
    public function orderList($requestData, $user)
    {
        $type = $requestData['type'] ?? 0;
        $page = $requestData['page'] ?? 1;
        $limit = $requestData['limit'] ?? 0;
        $where = [['is_delete', '=', 1], ['user_id', '=', $user['id']]];
        if (!in_array($type, [0, 1, 2, 3])) {
            return ['status' => 0, 'message' => '请求类型错误', 'result' => ''];
        }
        if (!$type) {
            $where[] = ['status', 'in', '2,3,4,5'];
        } elseif ($type == 3) {
            $where[] = ['status', 'in', '3,4,5'];
        } elseif ($type == 1){
            $where[] = ['status', '=', '9'];
        } else {
            $where[] = ['status', 'in', $type];
        }
        //退款限制时间
        $refund_time = Config::where('name', 'refund_time')->value('value');
        //开门限制时间
        $open_time = Config::where('name', 'open_time')->value('value');
        $list = self::field('id,out_trade_no,venue_id,date,time_list,all_money,status,use_status,createtime')->with(
            'venue'
        )->where($where)->order('createtime', 'desc')->page($page, $limit)->select();

        if ($list) {
            foreach ($list as $key => $value) {
                $list[$key]['status_text'] = self::fetchStatus($value['status']);
                $list[$key]['use_status_text'] = self::fetchUseStatus($value['use_status']);
                $venue_images = explode(',', $value['venue_images']);
                $list[$key]['venue_images'] = $venue_images[0] ?? '';
                $time_list = json_decode($value['time_list'], true);
                $site_id_list = array_column($time_list, 'site_id');
                $site_list = Site::where('id', 'in', $site_id_list)->column('site_name', 'id');
                $time_data = [];
                foreach ($time_list as $k => $val) {
                    $time_list[$k]['site_name'] = $site_list[$val['site_id']];
                }
                $list[$key]['time_list'] = $time_list;

                $is_refund = false;//是否可退款
                if ((time() - $value['createtime'] < $refund_time * 3600) && $value['status'] == 2 && $value['use_status'] == 1) {
                    $is_refund = true;
                }
                $list[$key]['is_refund'] = $is_refund;
                $is_open = false;//是否可开门
                $timeData = array_column($time_list, 'time');

                $allTime = [];
                foreach ($timeData as $kk => $vv) {
                    if ($vv == '全天畅打') {
                        continue;
                    }
                    $newTime = explode('-', $vv);
                    $allTime[] = strtotime($value['date'] . ' ' . $newTime[0]);
                    $allTime[] = strtotime($value['date'] . ' ' . $newTime[1]);
                }
                if ($allTime) {
                    $min_time = min($allTime);
                    $max_time = max($allTime);
                    if ((time() >= $min_time - $open_time * 60) && (time() <= $max_time) && $value['status'] == 2) {
//                    $is_open = true;
                    }
                    $list[$key]['is_open'] = $is_open;
                }
            }
        }
        return ['status' => 1, 'message' => '操作成功', 'result' => $list];
    }

    /**
     * 订单详情.
     */
    public function orderDetails($requestData, $user)
    {
        $id = $requestData['id'] ?? 0;
        if (!$id) {
            return ['status' => 0, 'message' => '请求错误', 'result' => ''];
        }
        $order = self::field(
            'id,out_trade_no,venue_id,date,time_list,all_money,status,use_status,createtime,time_end,out_refund_no,refund_time,pay_type,cancel_time'
        )->with('venue')->where(['is_delete' => 1, 'id' => $id])->find();
        if (!$order) {
            return ['status' => 0, 'message' => '订单不存在', 'result' => ''];
        }
        $order['status_text'] = self::fetchStatus($order['status']);
        $order['use_status_text'] = self::fetchUseStatus($order['use_status']);
        $order['pay_type_text'] = self::fetchPayType($order['pay_type']);
        $venue_images = explode(',', $order['venue_images']);
        $order['venue_images'] = $venue_images[0] ?? '';
        $time_list = json_decode($order['time_list'], true);
        $site_id_list = array_column($time_list, 'site_id');
        $site_list = Site::where('id', 'in', $site_id_list)->column('site_name', 'id');
        foreach ($time_list as $k => $val) {
            $time_list[$k]['site_name'] = $site_list[$val['site_id']];
        }
        $order['time_list'] = $time_list;
        $order['createtime'] = date('Y-m-d H:i:s', $order['createtime']);
        $order['refund_time'] = $order['refund_time'] ? date(
            'Y-m-d H:i:s',
            $order['refund_time']
        ) : $order['refund_time'];
        $order['time_end'] = $order['time_end'] ? date('Y-m-d H:i:s', $order['time_end']) : $order['time_end'];
        $order['cancel_time'] = $order['cancel_time'] ? date(
            'Y-m-d H:i:s',
            $order['cancel_time']
        ) : $order['cancel_time'];
        //退款限制时间
        $refund_time = Config::where('name', 'refund_time')->value('value');
        $timeData = array_column($time_list, 'time');
        $allTime = [];
        foreach ($timeData as $kk => $vv) {
            if ($vv == '全天畅打') {
                continue;
            }
            $newTime = explode('-', $vv);
            $allTime[] = strtotime($order['date'] . ' ' . $newTime[0]);
            $allTime[] = strtotime($order['date'] . ' ' . $newTime[1]);
        }
        if ($allTime) {
            $min_time = min($allTime);
            $max_time = max($allTime);
            $order['is_refund'] = false;//是否可退款
            if ((time() < ($min_time - $refund_time * 3600)) && $order['status'] == 2 && $order['use_status'] == 1) {
                $order['is_refund'] = true;
            }
            $order['is_open'] = false;//是否可开门
        }

        $open_time = Config::where('name', 'open_time')->value('value');
        $timeData = array_column($order['time_list'], 'time');
        $allTime = [];
        foreach ($timeData as $kk => $vv) {
            if ($vv == '全天畅打') {
                continue;
            }
            $newTime = explode('-', $vv);
            $allTime[] = strtotime($order['date'] . ' ' . $newTime[0]);
            $allTime[] = strtotime($order['date'] . ' ' . $newTime[1]);
        }
        if ($allTime) {
            $min_time = min($allTime);
            $max_time = max($allTime);
            if ((time() >= $min_time - $open_time * 60) && (time() <= $max_time) && $order['status'] == 2) {
                $order['is_open'] = true;
            }
        }


        return ['status' => 1, 'message' => '操作成功', 'result' => $order];
    }

    /**
     * 去支付.
     */
    public function orderToPay($requestData, $user)
    {
        $id = $requestData['id'] ?? 0;
        if (!$id) {
            return ['status' => 0, 'message' => '请求错误', 'result' => ''];
        }
        Db::startTrans();
        try {
            $order = self::field(
                'id,out_trade_no,venue_id,date,time_list,all_money,status,use_status,createtime,time_end,out_refund_no,refund_time,pay_type,cancel_time'
            )->where(['is_delete' => 1, 'user_id' => $user['id'], 'id' => $id])->lock(true)->find();
            if (!$order) {
                return ['status' => 0, 'message' => '订单不存在', 'result' => ''];
            }
            $status_text = self::fetchStatus($order['status']);
            if ($order['status'] != 1) {
                return ['status' => 0, 'message' => '订单' . $status_text, 'result' => ''];
            }
            //去支付
            $result = $this->Pay($order, $user, 'orderNotify');
            Db::commit();
            if ($result) {
                $result['order_id'] = $order['id'];
                return ['status' => 1, 'message' => '请求成功', 'result' => $result];
            } else {
                return ['status' => 0, 'message' => '请求失败', 'result' => ''];
            }
        } catch (Exception $e) {
            Db::rollback();
            return ['status' => 1, 'message' => $e->getMessage(), 'result' => ''];
        }
        return ['status' => 1, 'message' => '操作成功', 'result' => $result];
    }

    /**
     * 申请退款.
     */
    public function orderRefund($requestData, $user)
    {
        $id = $requestData['id'] ?? 0;
        if (!$id) {
            return ['status' => 0, 'message' => '请求错误', 'result' => ''];
        }
//        Db::startTrans();
//        try {
        $order = self::field(
            'id,out_trade_no,venue_id,date,time_list,all_money,status,use_status,createtime,time_end,
            out_refund_no,refund_time,pay_type,cancel_time,user_id'
        )->where(['is_delete' => 1, 'user_id' => $user['id'], 'id' => $id])->find();
        if (!$order) {
            return ['status' => 0, 'message' => '订单不存在', 'result' => ''];
        }
        $time_list = json_decode($order['time_list'], true);
        $status_text = self::fetchStatus($order['status']);
        if ($order['status'] != 2) {
            return ['status' => 0, 'message' => '订单' . $status_text, 'result' => ''];
        }
        $use_status_text = self::fetchUseStatus($order['use_status']);
        if ($order['use_status'] != 1) {
            return ['status' => 0, 'message' => '订单' . $use_status_text, 'result' => ''];
        }
        $refund_time = Config::where('name', 'refund_time')->value('value');
        $timeData = array_column($time_list, 'time');
        $allTime = [];
        $refund_amount = $order['all_money'];

        if (!in_array('全天畅打', $timeData)) {
            foreach ($timeData as $kk => $vv) {
                $newTime = explode('-', $vv);
                $allTime[] = strtotime($order['date'] . ' ' . $newTime[0]);
                $allTime[] = strtotime($order['date'] . ' ' . $newTime[1]);
            }
            $min_time = min($allTime);
            $max_time = max($allTime);
            if (time() > ($min_time - 12 * 3600)) {  //扣除百分之五十
                $refund_amount = number_format($refund_amount * 50 /100, 2);
            }else if(time() < ($min_time - 12 * 3600) && ($max_time - 12 * 3600) > 48 * 3600){
                $amount = $order['all_money'] - $order['all_money'] * 30 / 100;
                $refund_amount = number_format($amount, 2);
            }
        }


        //申请退款
        $update = ['status' => 5];
        $out_refund_no = self::getOutRefundNo();
        $order['out_refund_no'] = $out_refund_no;
        if($order['pay_type'] == 2){
            //余额支付
            $user = (new User())->where(['id' => $order['user_id']])->find();
            $user_wallet = $user['wallet'] + $refund_amount;
            (new User())->where(['id' => $order['user_id']])->update(['wallet' => $user_wallet]);

            $update['out_refund_no'] = $out_refund_no;
            $update['refund_time'] = time();
            $update['refund_money'] = $refund_amount;
            $result = self::where('id', $id)->update($update);
            $platform_log = [
                'user_id' => $user['id'],
                'amount' =>$refund_amount,
                'type' => 2,
                'log_note' => '订单退款',
                'order_id' => $order['id'],
                'createtime' => time(),
            ];
            PlatformLog::insert($platform_log);

            //添加记录
            $userBill['user_id'] = $order['user_id'];
            $userBill['title'] = '取消订单';
            $userBill['type'] = 1;
            $userBill['amount'] = $refund_amount;
            (new UserBill())->addUserBill($userBill);
            return ['status' => 1, 'message' => '请求成功', 'result' => []];
        }else{
            //微信支付
            $res = self::refund($order, $user,$refund_amount);

            Db::name('log')->insert(['content' => json_encode($res, 256)]);
            if ($res['return_code'] == 'SUCCESS' && $res['result_code'] == 'SUCCESS') {
                $update['out_refund_no'] = $out_refund_no;
                $update['refund_id'] = $res['refund_id'];
                $update['refund_time'] = time();
                $update['refund_money'] = bcdiv($refund_amount, 100, 2);
                $result = self::where('id', $id)->update($update);
                //写入平台流水
                $platform_log = [
                    'user_id' => $user['id'],
                    'amount' => -$order['all_money'],
                    'type' => 2,
                    'log_note' => '订单退款',
                    'order_id' => $order['id'],
                    'createtime' => time(),
                ];
                PlatformLog::insert($platform_log);
                return ['status' => 1, 'message' => '请求成功', 'result' => []];
            } else {
                return ['status' => 0, 'message' => '退款失败,请联系平台客服', 'result' => ''];
            }

        }


//            Db::commit();
//        } catch (Exception $e) {
//            Db::rollback();
////            return ['status' => 0, 'message' => $e->getMessage(), 'result' => ''];
//            return ['status' => 0, 'message' => '退款失败,请联系平台客服', 'result' => ''];
//        }
    }

    /**
     * 取消订单.
     */
    public function orderCancel($requestData, $user)
    {
        $id = $requestData['id'] ?? 0;
        if (!$id) {
            return ['status' => 0, 'message' => '请求错误', 'result' => ''];
        }
        Db::startTrans();
        try {
            $order = self::field(
                'id,out_trade_no,venue_id,date,time_list,all_money,status,use_status,createtime,time_end,out_refund_no,refund_time,pay_type,cancel_time'
            )->where(['is_delete' => 1, 'user_id' => $user['id'], 'id' => $id])->lock(true)->find();
            if (!$order) {
                return ['status' => 0, 'message' => '订单不存在', 'result' => ''];
            }
            $status_text = self::fetchStatus($order['status']);
            if ($order['status'] != 1) {
                return ['status' => 0, 'message' => '订单' . $status_text, 'result' => ''];
            }
            $result = self::where('id', $id)->update(['status' => 4, 'cancel_time' => time()]);
            Db::commit();
            if ($result) {
                return ['status' => 1, 'message' => '请求成功', 'result' => ''];
            } else {
                return ['status' => 0, 'message' => '请求失败', 'result' => ''];
            }
        } catch (Exception $e) {
            Db::rollback();
            return ['status' => 1, 'message' => $e->getMessage(), 'result' => ''];
        }
        return ['status' => 1, 'message' => '操作成功', 'result' => $order];
    }

    /**
     * 预约下单页.
     */
    public function orderPage($requestData, $user)
    {
        $user_is_vip = $user['is_vip'] ?? 0;
        $venue_id = $requestData['venue_id'] ?? 0;
        $date = $requestData['date'] ?? date('Y-m-d');
        if (!$venue_id) {
            return ['status' => 0, 'message' => '请求错误', 'result' => ''];
        }
        $venue = Venue::where(['is_delete' => 1, 'status' => 1])->find();
        if (!$venue) {
            return ['status' => 0, 'message' => '场馆不存在', 'result' => ''];
        }
        //可预约天数
        $bookable_days = Config::where('name', 'bookable_days')->value('value');
        $limit = $bookable_days >= 0 ? $bookable_days : 0;
        //日期列表
        $date_list = Date::field('id,date,status')->where(['venue_id' => $venue_id])->whereTime(
            'date',
            '>=',
            date('Y-m-d')
        )->order('date asc')->limit($limit)->select();
        $week_list = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
        $date_status = 1;//当前日期状态
        if ($date_list) {
            foreach ($date_list as $kyy => $vll) {
                $date_list[$kyy]['new_date'] = date('m-d', strtotime($vll['date']));
                $date_list[$kyy]['week'] = $week_list[date('w', strtotime($vll['date']))];
                if ($vll['date'] == $date) {
                    $date_status = $vll['status'];
                }
            }
        }
        //特殊日期
        $special_date = DateSpecial::where(['venue_id' => $venue_id, 'date' => $date])->column('time_list', 'site_id');
        //周锁场列表
        $week = date('w', strtotime($date));
        $week_lock_list = WeekSpecial::where(['status' => 1, 'week' => $week, 'venue_id' => $venue_id])->column(
            'time_list',
            'site_id'
        );
        $new_week_lock_list = [];
        foreach ($week_lock_list as $ss => $tt) {
            $tt_time_list = json_decode($tt, true);
            $week_status_list = [];
            $week_price_list = [];
            $week_vip_price_list = [];
            foreach ($tt_time_list as $hh => $ll) {
                $week_status_list[$ll['time']] = $ll['status'];
                $week_price_list[$ll['time']] = $ll['price'];
                $week_vip_price_list[$ll['time']] = $ll['vip_price'] ?? $ll['price'];
            }
            $new_week_lock_list[$ss] = [
                'week_status_list' => $week_status_list,
                'week_price_list' => $week_price_list,
                'week_vip_price_list' => $week_vip_price_list,
            ];
        }


        $rule_type = $venue['rule_type'];
        //时间列表
        $time_list = Time::where(['venue_id' => $venue_id])->column(['start_time', 'end_time', 'status'], 'id');
        $new_time_list = [];
        foreach ($time_list as $kkk => $vvv) {
            $new_time_list[$vvv['start_time'] . '-' . $vvv['end_time']] = $vvv['status'];
        }
        //场地列表
        $site_list = Site::field('id,site_name,time_list')->where(
            ['is_delete' => 1, 'status' => 1, 'venue_id' => $venue_id]
        )->order('createtime asc')->select()->toArray();
        //订单
        $order_list = Order::where(['is_delete' => 1, 'date' => $date, 'status' => [2, 3], 'is_sc' => 0])->column(
            'time_list'
        );
        if ($site_list) {
            foreach ($site_list as $key => $value) {
                $week_status_data = $new_week_lock_list[$value['id']]['week_status_list'] ?? [];
                $week_price_data = $new_week_lock_list[$value['id']]['week_price_list'] ?? [];
                $week_vip_price_data = $new_week_lock_list[$value['id']]['week_vip_price_list'] ?? [];
                $time_list = json_decode($value['time_list'], true);
                if (array_key_exists($value['id'], $special_date)) {
                    $special_time_list = json_decode($special_date[$value['id']], true);
                }
                foreach ($time_list as $k => $val) {
                    $status = ($date_status == 2) ? $date_status : $new_time_list[$val['time']];
                    if ($week_status_data && $status == 1) {
                        $status = $week_status_data[$val['time']];
                    }
                    if ($week_price_data) {
                        $time_list[$k]['price'] = $week_price_data[$val['time']];
                    }
                    if($user_is_vip == 1 && $week_vip_price_data){
                        $time_list[$k]['price'] = $week_vip_price_data[$val['time']];

                    }
                    if (isset($special_time_list)) {
                        $specialTime = array_column($special_time_list, 'price', 'time');
                        $time_list[$k]['price'] = $specialTime[$val['time']];
                    }
                    $time = explode('-', $val['time']);

                    //判断同场地 同时段 是否有预订
                    if ($status == 1 && $order_list) {
                        foreach ($order_list as $ko => $vo) {
                            $order_time = json_decode($vo, true);
                            foreach ($order_time as $kn => $v) {
                                $is_day = $v['is_sc'] ?? 0;
                                if ($is_day == 1) {
                                    continue;
                                }
                                $old_time = explode('-', $v['time']);
                                $start_time = strtotime($old_time[0]) ?? '';
                                $end_time = strtotime($old_time[1]) ?? '';
                                $is_check = false;
                                if ($rule_type == 1) {
                                    //判断预定规则1
                                    if ($value['id'] == 4 && ($v['site_id'] == 1 || $v['site_id'] == 2)) {//篮球场1：判断 羽毛球场1、羽毛球场2 同时段是否已定
                                        $is_check = true;
                                    } elseif ($value['id'] == 5 && ($v['site_id'] == 2 || $v['site_id'] == 3)) {//篮球场2：判断 羽毛球场2、羽毛球场3 同时段是否已定
                                        $is_check = true;
                                    } elseif ($value['id'] == 1 && $v['site_id'] == 4) {//羽毛球场1：判断 篮球场1是否已定
                                        $is_check = true;
                                    } elseif ($value['id'] == 2 && in_array($v['site_id'], [1, 3, 4, 5]
                                        )) {//羽毛球场2：判断其他所有篮球场和2、3号羽毛球场是否已定
                                        $is_check = true;
                                    } elseif ($value['id'] == 3 && $v['site_id'] == 5) {//羽毛球场2：篮球场2是否已定
                                        $is_check = true;
                                    } elseif ($value['id'] == $v['site_id'] && !in_array($value['id'], [6, 7]
                                        )) {//同一场地 判断同时段是否已定
                                        $is_check = true;
                                    }
                                }

                                //判断是否有时间已预订
                                if ($is_check) {
                                    if (($start_time >= strtotime($time[0]) && $start_time < strtotime(
                                                $time[1]
                                            )) || ($end_time > strtotime($time[0]) && $end_time <= strtotime(
                                                $time[1]
                                            )) || ($start_time >= strtotime($time[0]) && $end_time <= strtotime(
                                                $time[1]
                                            )) || ($start_time <= strtotime($time[0]) && $end_time >= strtotime(
                                                $time[1]
                                            ))) {
                                        $status = 2;
                                    }
                                }
                            }
                        }
                    }
                    $time_list[$k]['status'] = $status;

                    $time_list[$k]['start_time'] = $time[0];
                    $time_list[$k]['end_time'] = $time[1];

                    if (strtotime($date . ' ' . $time[0]) < time()) {
                        $time_list[$k]['status'] = 2;
                    }


                    $time_list[$k]['id'] = $k + 1;
                    $time_list[$k]['site_id'] = $value['id'];
                    $time_list[$k]['site_name'] = $value['site_name'];
                }
                $site_list[$key]['time_list'] = $time_list;
            }
        }
        $result_data = [
            'date_list' => $date_list,
            'site_list' => $site_list,
        ];
        return ['status' => 1, 'message' => '请求成功', 'result' => $result_data];
    }

    /**
     * 预约下单提交.
     */
    public function orderPay($requestData, $user)
    {
        $venue_id = $requestData['venue_id'] ?? 0;
        $date = $requestData['date'] ?? '';
        $all_money = $requestData['all_money'] ?? 0;
        $time_list = $requestData['time_list'] ?? [];
        $pay_type = $requestData['pay_type'] ?? 'weixin';


        if (!$venue_id || !$date || !$all_money || !$time_list) {
            return ['status' => 0, 'message' => '请求错误', 'result' => ''];
        }
        Db::startTrans();
        try {
            $last_order = Order::order('createtime desc')->lock(true)->value('createtime');
            if (time() - $last_order < 2) {
                return ['status' => 0, 'message' => '提交频繁，请稍后再试', 'result' => ''];
            }
            $venue = Venue::where(['is_delete' => 1, 'status' => 1])->lock(true)->find();
            if (!$venue) {
                return ['status' => 0, 'message' => '场馆不存在', 'result' => ''];
            }
            if (strtotime($date) < strtotime(date('Y-m-d') . ' 00:00:00')) {
                return ['status' => 0, 'message' => '该日期不可预定', 'result' => ''];
            }
            $dateData = Date::where(['date' => $date, 'venue_id' => $venue_id, 'status' => 1])->lock(true)->count();
            if (!$dateData) {
                return ['status' => 0, 'message' => '该日期不可预定', 'result' => ''];
            }
            //场馆时间段
            $timeList = Time::where(['venue_id' => $venue_id, 'status' => 2])->lock(true)->column(
                'start_time,end_time'
            );
            //特殊日期
            $special_date = DateSpecial::where(['venue_id' => $venue_id, 'date' => $date])->column(
                'time_list',
                'site_id'
            );
            //周锁场列表
            $week = date('w', strtotime($date));
            $week_lock_list = WeekSpecial::where(['status' => 1, 'week' => $week, 'venue_id' => $venue_id])->column(
                'time_list',
                'site_id'
            );
            //判断时间段是否可选
            foreach ($time_list as $kk => $vv) {
                $new_time = explode('-', $vv['time']);
                $new_start_time = strtotime($date . ' ' . $new_time[0]);
                $new_end_time = strtotime($date . ' ' . $new_time[1]);
                if ($date == date('Y-m-d')) {
                    if ($new_start_time <= time() || $new_end_time <= time()) {
                        return ['status' => 0, 'message' => '预约时间已过', 'result' => ''];
                    }
                }
                //判断是否有时间小于1小时
                if ($new_end_time - $new_start_time < 3600) {
                    return ['status' => 0, 'message' => '最低一小时起订', 'result' => ''];
                }
                //判断是否有时间不可选(场馆时间段检测)
                foreach ($timeList as $vvv) {
                    $start_time = strtotime($date . ' ' . $vvv['start_time']);
                    $end_time = strtotime($date . ' ' . $vvv['end_time']);
                    if (($start_time >= $new_start_time && $start_time < $new_end_time) || ($end_time > $new_start_time && $end_time <= $new_end_time) || ($start_time >= $new_start_time && $end_time <= $new_end_time) || ($start_time <= $new_start_time && $end_time >= $new_end_time)) {
                        return ['status' => 0, 'message' => '有时间段不可选1', 'result' => ''];
                    }
                }


                //判断是否有时间不可选(锁场时间段检测)
                if ($week_lock_list) {
                    $new_week_lock_list = (isset($week_lock_list[$vv['site_id']]) && !empty($week_lock_list[$vv['site_id']])) ? json_decode(
                        $week_lock_list[$vv['site_id']],
                        true
                    ) : [];
                    foreach ($new_week_lock_list as $vss) {
                        if ($vss['status'] == 2) {
                            $time_vss = explode('-', $vss['time']);
                            $lock_start_time = strtotime($date . ' ' . $time_vss[0]);
                            $lock_end_time = strtotime($date . ' ' . $time_vss[1]);
                            if (($lock_start_time >= $new_start_time && $lock_start_time < $new_end_time) || ($lock_end_time > $new_start_time && $lock_end_time <= $new_end_time) || ($lock_start_time >= $new_start_time && $lock_end_time <= $new_end_time) || ($lock_start_time <= $new_start_time && $lock_end_time >= $new_end_time)) {
                                return ['status' => 0, 'message' => '有时间段不可选3', 'result' => ''];
                            }
                        }
                    }
                }
            }
            //判断订单
            $order_list = Order::where(['is_delete' => 1, 'date' => $date, 'is_sc' => 0])->whereIn(
                'status',
                '1,2,3'
            )->lock(
                true
            )->chunk(10, function ($orders) use ($venue, $venue_id, $time_list, $timeList, $date) {
                //预约判定规则
                if ($venue['rule_type'] == 1 && in_array($venue_id, [1, 2])) {//判断规则1

                    $res = self::orderRule1($time_list, $orders, $timeList, $date, $venue['rule_type']);
                    if ($res['status'] == 0) {
                        return ['status' => 0, 'message' => $res['message'], 'result' => ''];
                    }
                }
            });

            $order = [
                'out_trade_no' => self::getOutTradeNo(),
                'user_id' => $user['id'],
                'venue_id' => $venue_id,
                'date' => $date,
                'time_list' => json_encode($time_list, JSON_UNESCAPED_UNICODE),
                'all_money' => $all_money,
                'createtime' => time(),
                'pay_type' => 1,
            ];
            if ($pay_type == 'yue') {
                //余额支付
                $order['status'] = 2;
                $order['pay_type'] = 2;
            }

            $order_id = self::insertGetId($order);
            $order['id'] = $order_id;

            if ($pay_type == 'yue') {
                //扣除余额
                $user = (new User())->where(['id' => $user['id']])->find();
                $userWallet = $user['wallet'] - $all_money;
                if ($userWallet < 0) {
                    return ['status' => 0, 'message' => '余额不足', 'result' => ''];
                }
                Db::name('user')->where(['id' => $user['id']])->update(['wallet' => $userWallet]);
                $res['user_id'] = $user['id'];
                $res['title'] = '预约散客场';
                $res['type'] = 2;
                $res['amount'] = $all_money;
                $res['create_time'] = time();
                Db::name('user_bill')->insert($res);
                $result['code'] = 1;
            } else {
                $result = $this->Pay($order, $user, 'orderNotify');
            }
            //去支付
            Db::commit();
            if ($result) {
                $result['order_id'] = $order_id;
                return ['status' => 1, 'message' => '请求成功', 'result' => $result];
            } else {
                return ['status' => 0, 'message' => '请求失败', 'result' => ''];
            }
        } catch (Exception $e) {
            Db::rollback();
            return ['status' => 0, 'message' => $e->getMessage(), 'result' => ''];
        }
    }


    public function orderPays($requestData, $user)
    {
        $venue_id = $requestData['venue_id'] ?? 0;
        $date = $requestData['date'] ?? '';
        $pay_type = $requestData['pay_type'] ?? 'weixin';
        $all_money = $requestData['all_money'] ?? 0;
        $time_list_new = $requestData['time_list'] ?? [];


        $time_list = [];

// 用来记录已处理过全天畅打的 site_id
        $allDayProcessed = [];


        if($user['is_vip'] == 1){
            $allDayPrice = (new Config())->where(['id' => 49])->value('value');

        }else{
            $allDayPrice = (new Config())->where(['id' => 48])->value('value');
        }
        foreach ($time_list_new as $item) {
            if ($item['isAllDay'] == 1) {
                // 检查是否已经处理过这个 site_id 的全天畅打
                if (!in_array($item['site_id'], $allDayProcessed)) {
                    $allDayProcessed[] = $item['site_id']; // 记录 site_id
                    $item['time'] = '全天畅打'; // 更改 time 字段
                    $item['money'] = $allDayPrice; // 设置自定义价格            $result[] = $item; // 添加到结果数组
                    $time_list[] = $item; // 添加到结果数组

                }
            } else {
                // 如果不是全天畅打，并且这个 site_id 还没有处理过全天畅打
                if (!in_array($item['site_id'], $allDayProcessed)) {
                    $time_list[] = $item; // 添加到结果数组
                }
            }
        }
        if (!$venue_id || !$date || !$all_money || !$time_list) {
            return ['status' => 0, 'message' => '请求错误', 'result' => ''];
        }
        Db::startTrans();
        try {
            $last_order = Order::order('createtime desc')->lock(true)->value('createtime');
            if (time() - $last_order < 2) {
                return ['status' => 0, 'message' => '提交频繁，请稍后再试', 'result' => ''];
            }
            $venue = Venue::where(['is_delete' => 1, 'status' => 1])->lock(true)->find();
            if (!$venue) {
                return ['status' => 0, 'message' => '场馆不存在', 'result' => ''];
            }
            if (strtotime($date) < strtotime(date('Y-m-d') . ' 00:00:00')) {
                return ['status' => 0, 'message' => '该日期不可预定', 'result' => ''];
            }
            $dateData = Date::where(['date' => $date, 'venue_id' => $venue_id, 'status' => 1])->lock(true)->count();
            if (!$dateData) {
                return ['status' => 0, 'message' => '该日期不可预定', 'result' => ''];
            }


            $order = [
                'out_trade_no' => self::getOutTradeNo(),
                'user_id' => $user['id'],
                'venue_id' => $venue_id,
                'date' => $date,
                'time_list' => json_encode($time_list, JSON_UNESCAPED_UNICODE),
                'all_money' => $all_money,
                'createtime' => time(),
                'is_sc' => 1,
                'pay_type' =>1
            ];

            if ($pay_type == 'yue') {
                //余额支付
                $order['status'] = 2;
                $order['pay_type'] = 2;

            }


            $order_id = self::insertGetId($order);
            $order['id'] = $order_id;
            if ($pay_type == 'yue') {
                //扣除余额
                $user = (new User())->where(['id' => $user['id']])->find();
                $userWallet = $user['wallet'] - $all_money;
                if ($userWallet < 0) {
                    return ['status' => 0, 'message' => '余额不足', 'result' => ''];
                }
                Db::name('user')->where(['id' => $user['id']])->update(['wallet' => $userWallet]);
                $res['user_id'] = $user['id'];
                $res['title'] = '预约散客场';
                $res['type'] = 2;
                $res['amount'] = $all_money;
                $res['create_time'] = time();
                Db::name('user_bill')->insert($res);
                $result['code'] = 1;
            } else {
                $result = $this->Pay($order, $user, 'orderNotify');
            }
            //去支付
            Db::commit();
            if ($result) {
                $result['order_id'] = $order_id;
                return ['status' => 1, 'message' => '请求成功', 'result' => $result];
            } else {
                return ['status' => 0, 'message' => '请求失败', 'result' => ''];
            }
        } catch (Exception $e) {
            Db::rollback();
            print_r($e->getMessage());
            die;
            return ['status' => 0, 'message' => $e->getMessage(), 'result' => ''];
        }
    }


    /**
     *判断预定规则1（同时段内）
     *篮球场1：判断 羽毛球场1、羽毛球场2 是否已定
     *篮球场2：判断 羽毛球场2、羽毛球场3 是否已定
     *羽毛球场1：判断 篮球场1是否已定
     *羽毛球场2：判断其他所有篮球场和2、3号羽毛球场是否已定
     *羽毛球场3：篮球场2是否已定
     *
     * @param        $time_list   预定时间段列表
     * @param        $order_list  该场馆同一日的订单列表
     * @param        $timeList    该场馆所有时间段列表
     * @param        $date        日期
     * @param string $notify_url
     *
     * @return array|false|string
     */
    public static function orderRule1($time_list = [], $order_list = [], $timeList = [], $date, $rule_type = 1)
    {
        foreach ($time_list as $kk => $vv) {
            $new_time = explode('-', $vv['time']);
            $new_start_time = strtotime($new_time[0]);
            $new_end_time = strtotime($new_time[1]);

            foreach ($order_list as $key => $value) {
                $order_time = json_decode($value['time_list'], true);
                foreach ($order_time as $k => $v) {
                    $old_time = explode('-', $v['time']);

                    $start_time = strtotime($old_time[0]);
                    $end_time = strtotime($old_time[1]);
                    $is_check = false;
                    if ($rule_type == 1) {
                        //判断预定规则1
                        if ($vv['site_id'] == 4 && ($v['site_id'] == 1 || $v['site_id'] == 2)) {//篮球场1：判断 羽毛球场1、羽毛球场2 同时段是否已定
                            $is_check = true;
                        } elseif ($vv['site_id'] == 5 && ($v['site_id'] == 2 || $v['site_id'] == 3)) {//篮球场2：判断 羽毛球场2、羽毛球场3 同时段是否已定
                            $is_check = true;
                        } elseif ($vv['site_id'] == 1 && $v['site_id'] == 4) {//羽毛球场1：判断 篮球场1是否已定
                            $is_check = true;
                        } elseif ($vv['site_id'] == 2 && in_array($v['site_id'], [1, 3, 4, 5]
                            )) {//羽毛球场2：判断其他所有篮球场和2、3号羽毛球场是否已定
                            $is_check = true;
                        } elseif ($vv['site_id'] == 3 && $v['site_id'] == 5) {//羽毛球场2：篮球场2是否已定
                            $is_check = true;
                        } elseif ($v['site_id'] == $vv['site_id']) {//同一场地 判断同时段是否已定
                            $is_check = true;
                        }
                    }
                    //判断是否有时间已预订
                    if ($is_check) {
                        if (($start_time >= $new_start_time && $start_time < $new_end_time) || ($end_time > $new_start_time && $end_time <= $new_end_time) || ($start_time >= $new_start_time && $end_time <= $new_end_time) || ($start_time <= $new_start_time && $end_time >= $new_end_time)) {
                            return ['status' => 0, 'message' => '有时间段已被预订', 'result' => ''];
                        }
                    }
                }
            }
        }
        return ['status' => 1, 'message' => '', 'result' => ''];
    }

    /**
     * 开锁.
     */
    public function openDoor($requestData, $user)
    {
        $order_id = $requestData['order_id'] ?? 0;
        if (!$order_id) {
            return ['status' => 0, 'message' => '请求错误', 'result' => ''];
        }
        $order = self::field(
            'id,out_trade_no,venue_id,date,time_list,all_money,status,use_status,createtime,time_end,out_refund_no,refund_time,pay_type,cancel_time'
        )->where(['is_delete' => 1, 'user_id' => $user['id'], 'id' => $order_id])->lock(true)->find();
        if (!$order) {
            return ['status' => 0, 'message' => '订单不存在', 'result' => ''];
        }
        $status_text = self::fetchStatus($order['status']);
        if ($order['status'] != 2) {
            return ['status' => 0, 'message' => '订单' . $status_text, 'result' => ''];
        }
        //开门限制时间
        $open_time = Config::where('name', 'open_time')->value('value');
        $time_list = json_decode($order['time_list'], true);
        $timeData = array_column($time_list, 'time');
        $allTime = [];
        foreach ($timeData as $kk => $vv) {
            $newTime = explode('-', $vv);
            $allTime[] = strtotime($order['date'] . ' ' . $newTime[0]);
            $allTime[] = strtotime($order['date'] . ' ' . $newTime[1]);
        }
        $min_time = min($allTime);
        $max_time = max($allTime);
        if ((time() < $min_time - $open_time * 60) || (time() > $max_time)) {
            return ['status' => 0, 'message' => '未到开门时间或开门时间已过', 'result' => ''];
        }
        $url = 'https://www.wmj.com.cn/api/oplock';
        $gateinfo = Config::field('name,value')->where('group', 'gateinfo')->column('value', 'name');
        $data = [
            'sn' => $gateinfo['sn_number'],
            'appid' => $gateinfo['appid'],
            'appsecret' => $gateinfo['appsecret'],
        ];
        $result = curl_post_https($url, $data);
        if (isset($result['state']) && $result['state'] == 1) {
            return ['status' => 1, 'message' => '开门成功', 'result' => ''];
        } else {
            return ['status' => 0, 'message' => '开门失败', 'result' => ''];
        }
    }

    /**
     * 注册.
     */
    public function registerDoor($requestData, $user)
    {
        $url = 'https://www.wmj.com.cn/api/reglock';
        $gateinfo = Config::field('name,value')->where('group', 'gateinfo')->column('value', 'name');
        $data = [
            'sn' => $gateinfo['sn_number'],
            'appid' => $gateinfo['appid'],
            'appsecret' => $gateinfo['appsecret'],
        ];
        $result = curl_post_https($url, $data);
        if (isset($result['state']) && $result['state'] == 1) {
            return ['status' => 1, 'message' => '注册成功', 'result' => ''];
        } else {
            return ['status' => 0, 'message' => '注册失败', 'result' => ''];
        }
    }

    //小程序支付调用
    public static function Pay($order, $user, $notify_url = 'orderNotify')
    {
        $config = \think\facade\Config::get('config_wechat.wechat_pay');
        $app = Factory::payment($config);
        $jssdk = $app->jssdk;
        $result = $app->order->unify([
            'body' => '预约下单',
            'out_trade_no' => $order['out_trade_no'],
            'total_fee' => $order['all_money'] * 100,
            'notify_url' => config('fastadmin.api_url') . '/api/notify/' . $notify_url,
            'trade_type' => 'JSAPI',
            'openid' => $user['openid']
        ]);
        if ($result['return_code'] != "SUCCESS" || $result['result_code'] != 'SUCCESS') {
            return false;
        }
        $config = $jssdk->bridgeConfig($result['prepay_id'], false);
        if (!$config) {
            return false;
        }
        return $config;
    }

    //退款
    public static function refund($order, $user,$refund_amount)
    {
        $config = \think\facade\Config::get('config_wechat.wechat_pay');
        $app = Factory::payment($config);

        $result = $app->refund->byOutTradeNumber(
            $order['out_trade_no'],
            $order['out_refund_no'],
            $order['all_money'] * 100,
            $refund_amount * 100,
            [
                // 可在此处传入其他参数，详细参数见微信支付文档
                'refund_desc' => '订单退款',
            ]
        );
        return $result;
    }

    //生成唯一订单号
    public static function getOutTradeNo()
    {
        $out_trade_no = sys_create_orderno(1);
        $order = self::where('out_trade_no', $out_trade_no)->count();
        if ($order) {
            self::getOutTradeNo();
        }
        return $out_trade_no;
    }

    //生成唯一退款号
    public static function getOutRefundNo()
    {
        $out_refund_no = sys_create_orderno(4);
        $order = self::where('out_refund_no', $out_refund_no)->count();
        if ($order) {
            self::getOutRefundNo();
        }
        return $out_refund_no;
    }

    //订单状态处理
    public static function fetchStatus($status = null)
    {
        $data = [
            1 => '待支付',
            2 => '已支付',
            3 => '已完成',
            4 => '已取消',
            5 => '已退款',
        ];
        if (isset($data[$status])) {
            return $data[$status];
        } else {
            return $data;
        }
    }

    public function venue()
    {
        return $this->hasOne('venue', 'id', 'venue_id')->bind(['venue_name', 'venue_images']);
    }

    //使用状态处理
    public static function fetchUseStatus($use_status = null)
    {
        $data = [
            1 => '未使用',
            2 => '使用中',
            3 => '已使用',
        ];
        if (isset($data[$use_status])) {
            return $data[$use_status];
        } else {
            return $data;
        }
    }

    //支付方式
    public static function fetchPayType($pay_type = null)
    {
        $data = [
            1 => '微信支付',
            2=>'余额支付'
        ];
        if (isset($data[$pay_type])) {
            return $data[$pay_type];
        } else {
            return $data;
        }
    }

    public static function checkTimeList($time_list)
    {
        $allArr = [];
        $timeStr = '';
        $money = 0;
        if ($time_list) {
            foreach ($time_list as $key => $value) {
                if ($key > 0) {
                    if ($value['start_time'] != $time_list[$key - 1]['end_time']) {
                        $valueArr = [
                            'site_id' => $value['site_id'],
                            'time' => $timeStr . $time_list[$key - 1]['end_time'],
                            'money' => $money,
                        ];
                        $newTimeArr = explode('-', $valueArr['time']);
                        if (strtotime($newTimeArr[1]) - strtotime($newTimeArr[0]) > 30 * 60) {
                            $allArr[] = $valueArr;
                        }

                        $timeStr = $value['start_time'] . '-';
                        $money = $value['money'];
                    } else {
                        if ($key == count($time_list) - 1) {
                            $valueArr = [
                                'site_id' => $value['site_id'],
                                'time' => $timeStr . $value['end_time'],
                                'money' => $money + $value['money'],
                            ];
                            $newTimeArr = explode('-', $valueArr['time']);
                            if (strtotime($newTimeArr[1]) - strtotime($newTimeArr[0]) > 30 * 60) {
                                $allArr[] = $valueArr;
                            }
                        }
                        $money += $value['money'];
                    }
                } else {
                    $timeStr .= $value['start_time'] . '-';
                    $money += $value['money'];
                }
            }
        }
        return $allArr;
    }
}
